---
title: Session State for Multiple Users
---

This example demonstrates how to maintain separate session state for multiple users in a multi-user environment, with each user having their own shopping lists and sessions.

## Code

```python session_state_multiple_users.py
"""
This example demonstrates how to maintain state for each user in a multi-user environment.

The shopping list is stored in a dictionary, organized by user ID and session ID.

Agno automatically creates the "current_user_id" and "current_session_id" variables in the session state.

You can access these variables in your functions using the `agent.get_session_state()` dictionary.
"""

import json

from agno.agent import Agent
from agno.db.sqlite import SqliteDb
from agno.models.openai import OpenAIChat
from agno.run.base import run_context

# In-memory database to store user shopping lists
# Organized by user ID and session ID
shopping_list = {}


def add_item(run_context: RunContext, item: str) -> str:
    """Add an item to the current user's shopping list."""

    if not run_context.session_state:
        run_context.session_state = {}

    current_user_id = run_context.session_state["current_user_id"]
    current_session_id = run_context.session_state["current_session_id"]
    shopping_list.setdefault(current_user_id, {}).setdefault(
        current_session_id, []
    ).append(item)

    return f"Item {item} added to the shopping list"


def remove_item(run_context: RunContext, item: str) -> str:
    """Remove an item from the current user's shopping list."""

    if not run_context.session_state:
        run_context.session_state = {}

    current_user_id = run_context.session_state["current_user_id"]
    current_session_id = run_context.session_state["current_session_id"]

    if (
        current_user_id not in shopping_list
        or current_session_id not in shopping_list[current_user_id]
    ):
        return f"No shopping list found for user {current_user_id} and session {current_session_id}"

    if item not in shopping_list[current_user_id][current_session_id]:
        return f"Item '{item}' not found in the shopping list for user {current_user_id} and session {current_session_id}"

    shopping_list[current_user_id][current_session_id].remove(item)
    return f"Item {item} removed from the shopping list"


def get_shopping_list(run_context: RunContext) -> str:
    """Get the current user's shopping list."""

    if not run_context.session_state:
        run_context.session_state = {}

    current_user_id = run_context.session_state["current_user_id"]
    current_session_id = run_context.session_state["current_session_id"]
    return f"Shopping list for user {current_user_id} and session {current_session_id}: \n{json.dumps(shopping_list[current_user_id][current_session_id], indent=2)}"


# Create an Agent that maintains state
agent = Agent(
    model=OpenAIChat(id="gpt-5-mini"),
    db=SqliteDb(db_file="tmp/data.db"),
    tools=[add_item, remove_item, get_shopping_list],
    # Reference the in-memory database
    instructions=[
        "Current User ID: {current_user_id}",
        "Current Session ID: {current_session_id}",
    ],
    markdown=True,
)

user_id_1 = "john_doe"
user_id_2 = "mark_smith"
user_id_3 = "carmen_sandiago"

# Example usage
agent.print_response(
    "Add milk, eggs, and bread to the shopping list",
    stream=True,
    user_id=user_id_1,
    session_id="user_1_session_1",
)
agent.print_response(
    "Add tacos to the shopping list",
    stream=True,
    user_id=user_id_2,
    session_id="user_2_session_1",
)
agent.print_response(
    "Add apples and grapes to the shopping list",
    stream=True,
    user_id=user_id_3,
    session_id="user_3_session_1",
)
agent.print_response(
    "Remove milk from the shopping list",
    stream=True,
    user_id=user_id_1,
    session_id="user_1_session_1",
)
agent.print_response(
    "Add minced beef to the shopping list",
    stream=True,
    user_id=user_id_2,
    session_id="user_2_session_1",
)

# What is on Mark Smith's shopping list?
agent.print_response(
    "What is on Mark Smith's shopping list?",
    stream=True,
    user_id=user_id_2,
    session_id="user_2_session_1",
)

# New session, so new shopping list
agent.print_response(
    "Add chicken and soup to my list.",
    stream=True,
    user_id=user_id_2,
    session_id="user_3_session_2",
)

print(f"Final shopping lists: \n{json.dumps(shopping_list, indent=2)}")
```

## Usage

<Steps>
  <Snippet file="create-venv-step.mdx" />

  <Step title="Install libraries">
    ```bash
    pip install -U agno openai
    ```
  </Step>
  <Step title="Export your OpenAI API key">

    <CodeGroup>

    ```bash Mac/Linux
      export OPENAI_API_KEY="your_openai_api_key_here"
    ```

    ```bash Windows
      $Env:OPENAI_API_KEY="your_openai_api_key_here"
    ```
    </CodeGroup>
  </Step>

  <Step title="Create a Python file">
    Create a Python file and add the above code.
    ```bash
    touch session_state_multiple_users.py
    ```
  </Step>

  <Step title="Run Agent">
    <CodeGroup>
    ```bash Mac
    python session_state_multiple_users.py
    ```

    ```bash Windows
    python session_state_multiple_users.py
    ```
    </CodeGroup>
  </Step>

  <Step title="Find All Cookbooks">
  Explore all the available cookbooks in the Agno repository. Click the link below to view the code on GitHub:

  <Link href="https://github.com/agno-agi/agno/tree/main/cookbook/agents/state" target="_blank">
    Agno Cookbooks on GitHub
  </Link>
</Step>
</Steps>